<?php

namespace App\Console\Commands\User;

use App\Library\Rms\RmsUserApi;
use App\Models\Common\ConfigModel;
use App\Models\Common\FsCompanyModel;
use App\Models\Common\FsCompanySecondDepartmentModel;
use App\Models\Common\FsCompanyUserMappingModel;
use App\Models\Common\FsCompanyUserModel;
use App\Models\Common\FsOrganizationModel;
use App\Models\Cruise\CruiseCheckCompanyModel;
use App\Service\CallingCards\FeishuApiService;
use Illuminate\Console\Command;

class ExtUserUpdateV2 extends Command
{
    protected $signature = 'user:ext-user-update-v2 {orgId?} {departmentName?}';

    protected $description = '更新外部人员的fs_company_users表信息 v2';

    /**
     * 当前组织id
     */
    private int $organizationId;

    /**
     * 单独更新的部门名称
     * @var string
     */
    private string $argDepartmentName;

    public function handle()
    {
        // 后续更新，有效的用户仅剩供应链端用户 !!!

        // 仅更新该部门名称数据，不传更新全部
        $argDepartmentName = (string)$this->argument('departmentName');
        $argOrgId          = (int)$this->argument('orgId');

        $this->doHandle($argOrgId, $argDepartmentName);
    }

    public function doHandle(int $argOrgId, string $argDepartmentName)
    {
        $this->argDepartmentName = $argDepartmentName;

        FsOrganizationModel::query()
                           ->when($argOrgId, function ($query) use ($argOrgId) {
                               $query->where('id', $argOrgId);
                           })
                           ->get()
                           ->each(function (FsOrganizationModel $fsOrganizationModel) {

                               // 设置机构id
                               $this->organizationId = $fsOrganizationModel->id;

                               $this->writeInfo("--------------------- 机构：{$fsOrganizationModel->name} {$fsOrganizationModel->id} ---------------------");
                               $departments = FeishuApiService::getSupplierDepartments($this->organizationId, '0');

                               foreach ($departments['data']['items'] ?? [] as $item) {
                                   if ($item['name'] == '总部') {
                                       continue;
                                   }

                                   // 处理所有非总部的部门
                                   $this->doWhileRootDepartments($item['open_department_id']);
                               }
                           });

        // 自动关联工厂的config负责人
        $this->relationFactoryConfig();

        // 清空缓存
        CruiseCheckCompanyModel::forgetCompanyListsCache();

        $this->writeInfo("success");
    }

    /**
     * 分页循环获取供应商根本目录下的部门列表
     * @param string $pDepartmentId
     * @return void
     * @throws \Exception
     */
    private function doWhileRootDepartments(string $pDepartmentId)
    {
        $page_token = '';

        do {
            $departments = FeishuApiService::getSupplierDepartments($this->organizationId, $pDepartmentId, $page_token);
            $hasMore     = $departments['data']['has_more'] ?? false;
            $page_token  = $departments['data']['page_token'] ?? '';

            // 供应商根目录-部门列表
            $this->doSupplierRootDepartments($departments);
        } while ($hasMore);
    }

    // 供应商根目录-部门列表
    private function doSupplierRootDepartments(array $departments)
    {
        foreach ($departments['data']['items'] ?? [] as $company) {

            if ($this->argDepartmentName && $this->argDepartmentName != $company['name']) {
                continue;
            }

            $this->writeInfo("company:============ " . $company['name'] . ' ============');

            // fs_company add
            $fsCompany = FsCompanyModel::add($this->organizationId, $company['open_department_id'], $company['name']);
            $this->writeInfo($company['name'] . " id:{$fsCompany->id}");

            // 根目录下的用户处理
            $this->doUser($company, $fsCompany, FsCompanyUserMappingModel::BUSINESS_TYPE_ROOT);

            $page_token = '';
            do {
                // 获取供应商下的二级部门：品控、供应链...
                $secondDepartments = FeishuApiService::getSupplierDepartments($this->organizationId,
                    $company['open_department_id'], $page_token);
                $hasMore           = $secondDepartments['data']['has_more'] ?? false;
                $page_token        = $secondDepartments['data']['page_token'] ?? '';

                foreach ($secondDepartments['data']['items'] ?? [] as $secondDepartment) {

                    $secondDepartmentName = $secondDepartment['name'] ?? '';

                    $businessType = array_flip(FsCompanyUserMappingModel::BUSINESS_TYPE_TEXT)[$secondDepartmentName];

                    // fs_company_second_department add
                    FsCompanySecondDepartmentModel::add(
                        $fsCompany->id,
                        $secondDepartment['open_department_id'],
                        $secondDepartment['name'],
                        FsCompanyUserMappingModel::BUSINESS_TYPE_CRUISE_CHECK
                    );

                    // 处理用户新增入库
                    $this->doUser($secondDepartment, $fsCompany, $businessType);
                }

            } while ($hasMore);
        }
    }

    /**
     * 处理用户新增入库
     * @param array $department
     * @param FsCompanyModel $fsCompanyModel
     * @param int $businessType
     * @return void
     */
    private function doUser(array $department, FsCompanyModel $fsCompanyModel, int $businessType): void
    {
        $appId = FsOrganizationModel::getApiConfig($this->organizationId)['appID'];

        // 循环二级部门下的员工
        do {

            $users   = FeishuApiService::getUserInDepartments($this->organizationId, $department['open_department_id'],
                $users['data']['page_token'] ?? '');
            $hasMore = $users['data']['has_more'] ?? false;

            foreach ($users['data']['items'] ?? [] as $userInfo) {
                $mobile = substr($userInfo['mobile'] ?? '', -11);

                $data = [
                    'name'    => $username = $userInfo['name'] ?? '默认姓名',
                    'phone'   => $mobile,
                    'openId'  => $userInfo['open_id'] ?? '',
                    'unionId' => $userInfo['union_id'] ?? '',
                    'avatar'  => $userInfo['avatar']['avatar_72'] ?? '',
                    'ext'     => FsCompanyUserModel::EXT_OUT,
                ];

                // fs_company_users add
                $fsCompanyUser = FsCompanyUserModel::add($appId, $userInfo['user_id'], $data);

                $rmsUserId = $fsCompanyUser->rmsUserId;
                if (!$rmsUserId) {

                    // 调用rms用户基本信息
                    $rms = (new RmsUserApi())->getUserInfoByMobiles([$mobile])['data'][0] ?? [];

                    // 创建rms用户&职位
                    if (!isset($rms['id'])) {
                        $roleId    = (int)config('rms.cruiseCheckRoleId');
                        $rmsUserId = (new RmsUserApi())->createUser($mobile, $username,
                            [$roleId])['data']['userId'] ?? 0;
                    } else {
                        $rmsUserId = $rms['id'];
                    }

                    // 更新fs_company_users.rmsUserId
                    FsCompanyUserModel::saveRmsUserId($fsCompanyUser->id, $rmsUserId);
                }

                // fs_company_user_mappings add
                FsCompanyUserMappingModel::add($userInfo['user_id'], $fsCompanyModel->id, $businessType, $rmsUserId);

                // 针对二级部门做的相关业务
                $this->secondDepartmentNameFactory($businessType, $fsCompanyModel);

                $businessTypeText = FsCompanyUserMappingModel::BUSINESS_TYPE_TEXT[$businessType] ?: '根目录';
                $this->writeInfo("{$businessTypeText} user:{$username}");
            }

        } while ($hasMore);
    }

    // 针对二级部门做的相关业务
    private function secondDepartmentNameFactory(int $businessType, FsCompanyModel $fsCompanyModel): void
    {
        switch ($businessType) {
            case FsCompanyUserMappingModel::BUSINESS_TYPE_CRUISE_CHECK:

                list($_, $add) = ConfigModel::createCruiseCheckAudit($fsCompanyModel->departmentId,
                    $fsCompanyModel->name);

                if ($add) {
                    $this->writeInfo("新增机构：{$fsCompanyModel->name}");
                }

                break;

            default:
                break;
        }
    }

    // 自动关联工厂的config负责人
    private function relationFactoryConfig(): void
    {
        // 没有配置负责人的工厂
        ConfigModel::query()
                   ->where('module', 'cruiseCheck')
                   ->where('name', 'like', "companyAudit_%")
                   ->where('value', '[]')
                   ->get()
                   ->each(function (ConfigModel $configModel) {

                       $departmentId = substr($configModel->name, strlen('companyAudit_'));
                       if (!$departmentId) {
                           return;
                       }

                       $companyId = FsCompanyModel::query()->where('departmentId', $departmentId)->value('id');
                       if (!$companyId) {
                           return;
                       }

                       $companyManagerId = (int)CruiseCheckCompanyModel::query()
                                                                       ->where('fsCompanyId', $companyId)
                                                                       ->where('status',
                                                                           CruiseCheckCompanyModel::STATUS_ON)
                                                                       ->value('companyManagerId');
                       if (!$companyManagerId) {
                           return;
                       }

                       $configModel->value = json_encode([$companyManagerId]);
                       $configModel->save();

                       $this->writeInfo($configModel->description . "负责人更新成功：{$companyManagerId}");
                   });
    }

    private function writeInfo(string $text)
    {
        if (app()->runningInConsole()) {
            $this->info($text);
        } else {
            dump($text);
        }
    }
}
